import * as THREE from 'three';

// 加载字体相关附加组件
import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';
import { FontLoader } from 'three/addons/loaders/FontLoader.js';

/**
 * 为了真正能够让你的场景借助 three.js 来进行显示，
 * 需要以下几个对象：场景（scene）、相机（camera）和渲染器（renderer），
 * 就能透过摄像机渲染出场景。
 * */
const scene = new THREE.Scene();
/**
 * PerspectiveCamera（透视摄像机）
 * 第一个参数是视野角度（FOV）
 *    视野角度就是无论在什么时候，你所能在显示器上看到的场景的范围，它的单位是角度(与弧度区分开)。
 * 第二个参数是长宽比（aspect ratio）
 *    用一个物体的宽除以它的高的值。比如说，当你在一个宽屏电视上播放老电影时，可以看到图像仿佛是被压扁的。
 * 接下来的两个参数是近截面（near）和远截面（far）
 *    当物体某些部分比摄像机的远截面远或者比近截面近的时候，该这些部分将不会被渲染到场景中。
 *    或许现在你不用担心这个值的影响，但未来为了获得更好的渲染性能，你将可以在你的应用程序里去设置它。
 */
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

/**
 * 接下来是渲染器。
 *    在这里用到的 WebGLRenderer 渲染器之外，Three.js 同时提供了其他几种渲染器，当用户所使用的浏览器过于老旧，或者由于其他原因不支持 WebGL 时，可以使用这几种渲染器进行降级。
 */
const renderer = new THREE.WebGLRenderer();
/**
 *    还需要在我们的应用程序里设置一个渲染器的尺寸。比如说，我们可以使用所需要的渲染区域的宽高，来让渲染器渲染出的场景填充满我们的应用程序。
 *    因此，我们可以将渲染器宽高设置为浏览器窗口宽高。
 *    对于性能比较敏感的应用程序来说，可以使用 setSize 传入一个较小的值，例如 window.innerWidth/2 和 window.innerHeight/2，这将使得应用程序在渲染时，以一半的长宽尺寸渲染场景。
 *    如果希望保持应用程序的尺寸，但是以较低的分辨率来渲染，可在调用 setSize 时，将 updateStyle（第三个参数）设为 false。
 *    例如，假设你的 <canvas> 标签现在已经具有了 100% 的宽和高，调用 setSize(window.innerWidth/2, window.innerHeight/2, false) 将使得你的应用程序以四分之一的大小来进行渲染。
 *    最后一步很重要，我们将 renderer（渲染器）的dom元素（renderer.domElement）添加到我们的 HTML 文档中。这就是渲染器用来显示场景给我们看的 <canvas> 元素。
 */
renderer.setSize( window.innerWidth, window.innerHeight );
/**
 *    最后一步很重要，我们将 renderer（渲染器）的dom元素（renderer.domElement）添加到我们的 HTML 文档中。这就是渲染器用来显示场景给我们看的 <canvas> 元素。
 */
document.body.appendChild( renderer.domElement );

/**
 * 绘制文字
 */
const fontLoader = new FontLoader() // 创建字体加载器
fontLoader.load(
  // font资源URL
  './fonts/honor_sans_cn_regular/HONOR_Sans_CN_Regular.json',
  // onLoad回调
  function (font) {
    // 步骤一：创建对象
    const geometry = new TextGeometry('TRHEE.JS', {
      font: font, //THREE.Font的实例
      size: .8, // 字体大小 默认值100
      depth: .8, // 挤出文本的厚度 默认值50
      curveSegments: 100, // 文本的曲线上点的数量，默认12
      // bevelEnabled: true, //是否开启斜角 默认false
      // bevelThickness: 1, //文本上斜角的深度 默认20
      // bevelSize: 2, //斜角与原始文本轮廓之间的延伸距离 默认8
      // bevelSegments: 5 //斜角的分段数，默认3
    })
    geometry.center() // 居中文本
    // 步骤二： 给对象添加材质
    const materials = new THREE.MeshBasicMaterial({
      color: 0xE33F31,
      transparent: true,
      opacity: 0.6,
    })
    // 步骤三：使用对象、对象材质创建网格
    const textMesh = new THREE.Mesh(geometry, materials)

    textMesh.position.set(0,0,0)
    textMesh.position.y = 1.9

    camera.position.z = 5; //设置相机的位置
    textMesh.lookAt(camera.position)

    // 步骤四：将网格添加至场景中
    scene.add(textMesh)
    // 可选：在渲染循环中保持文字面向摄像机
    // 步骤五：真实渲染到页面中
    renderer.render(scene, camera)
  }
)
